import {Utils} from './Utils';
import {PanLogic} from '../PanLogic';
import {HashMap} from "./HashMap";

// 病患分布
const componentBase = (G as any).base.ComponentBase;
const component = componentBase.extend({
    // 属性
    options: {
        map: null,
        symbolConfig: null,
        highLightId: 'sicknessdistribute_sjts', // 高亮id
        popupId: 'popup_sicknessdistribute_sjts', // 弹窗唯一标识
        popupEventName: 'popup', // 详情框事件名
        featureType: 'sicknessdistribute_sjts', // 图层标识
        isLoading: false, // 是否正在执行异步操作
        hasTask: false, // 是否存在未完成的异步操作
    },
    // 初始化
    initialize(options: any) {
        componentBase.prototype.initialize.call(this, options);
        this.panLogic = new PanLogic(options)
    },
    //  销毁
    destroy() {
        componentBase.prototype.destroy.call(this);
    },

    load() {
        componentBase.prototype.load.call(this);
        //
        this._initOverlayWare();

        const {zoom, center} = this.options.mapConfig.map.fullExtent;
        this.map.zoomTo(zoom);
        const geo = new g2.sfs.Point({x: center[0], y: center[1]});
        this.map.setCenter(geo);
    },

    addListeners() {
        // 添加事件监听，load调用时父类触发
        this.map.listen('extentchanged', this._getSicknessByExtent, this);
    },

    unload() {
        componentBase.prototype.unload.call(this);
        // 移除业务图层
        this._clearLayers();
        this.panLogic.removePosition()
    },

    _clearLayers() {
        this.options.simpleRenderMgr.remove(this.options.featureType);
        if (this.overlayWare) {
            this.overlayWare.clear();
            this.overlayWare.remove();
            this.overlayWare = null;
        }
    },

    removeListeners() {
        // 移除事件监听，unload调用时父类触发
        this.map.off('extentchanged', this._getSicknessByExtent, this);
    },
    /**
     * 移除弹框
     */
        closePopup() {
        this.options.popupManager.remove(this.options.popupId);
        this._removeHighlight();
    },

    _initOverlayWare() {
        this.overlayWare = new g2.widget.OverlayWare({
            map: this.map
        });
    },
    _addOverlay(pos: any, ...numbers: any) {
        if (!numbers || numbers.length < 1) {
            return;
        }
        // let total: any = 0;
        let eleDom: any = '';
        const spanArr: any = [];

        const fontColors = this.options.symbolConfig.sickness_font_colors;
        let maxWidth = 0;
        let totalHeight = 0;
        numbers.forEach((num: any, i: number) => {
            num = num || 0;
            // spanArr.push(`<span style="color:${fontColors[i]};font-weight:bold">${num}</span>`);
            spanArr.push(`<p style="font-weight:normal;color:white;text-align: center;"><span style="color:${fontColors[i]};font-weight:bold">${num}</span>人</p>`);
            // total += num * 1;
            const {width, height} = Utils.getTextSize(num + '人');
            if (width > maxWidth) {
                maxWidth = width
            }
            totalHeight += height + 1;
        });
        // eleDom = `<div>${spanArr.join(',')}</div>`;
        eleDom = `<div>${spanArr.join('')}</div>`;

        // 测试添加overlay
        function parseDom(ele: any) {
            const div = document.createElement('div');
            div.className = 'sickness-distribution'
            div.innerHTML = ele;
            return div.childNodes[0];
        }

        const ele = parseDom(eleDom);
        // const { width, height } = Utils.getTextSize(numbers.join(','));
        const overlay = new g2.widget.OverLay({
            stopEvent: false,
            element: ele, // dom元素对象
            position: new g2.sfs.Point({
                x: pos.lng,
                y: pos.lat
            }), // 覆盖物在地图上停靠的位置
            offset: [Math.ceil(-maxWidth / 2 + 1), Math.ceil(-totalHeight / 2 + 2)] // 位置偏移量，根据覆盖物上展示的图标符号的大小来确定
        });

        this.overlayWare.add(overlay);
    },
    /**
     * 根据行政区划获取病患分布
     */
        getSicknessByDistrict(level: any, districtCode: any) {
        const extent = this.map.getExtent();
        this._getSicknessList(level, `${extent.minx},${extent.miny},${extent.maxx},${extent.maxy}`, districtCode);
    },
    /**
     * 根据当前视野范围变化获取病患分布
     */
        _getSicknessByExtent() {
        const extent = this.map.getExtent();
        if (!isNaN(extent.minx) && !isNaN(extent.miny) && !isNaN(extent.maxx) && !isNaN(extent.maxy)) {
            const zoom = Math.round(this.map.getZoomLevel());// 获取zoom
            // 根据zoom 获取level
            let level = this.options.symbolConfig.zoom_level_map[zoom] || 3;
            level = level === 4 ? 3 : level
            this._getSicknessList(level, `${extent.minx},${extent.miny},${extent.maxx},${extent.maxy}`)
        }
    },
    async _getSicknessList(level: any, bounds: any, districtCode: any) {
        if (this.options.isLoading) {
            this.options.hasTask = true;
            console.debug('isLoading 返回');
            return;
        }
        this.options.isLoading = true;
        try {
            const res: any = await this.options.service.getSicknessList(level, bounds);
            const list: any = res && res.data && res.data.data ? res.data.data : [];
            this._update(list);
            this.options.isLoading = false;
        } catch (err) {
            this.options.isLoading = false;
        }

        if (this.options.hasTask) {
            this.options.hasTask = false;
            this._getSicknessByExtent();
        }
    },

    async _update(list: any) {
        // const list: any = await this.options.service.getDemoData();
        const opts: any = {};
        opts.featureType = this.options.featureType;
        opts.idField = 'id'; // 数据唯一标识的属性
        opts.list = list; // 数据列表
        opts.type = 0; // 使用ElementLayer渲染
        opts.geometryBuilder = new this.options.PointGeometryBuilder({
            geometryField: ['lng', 'lat'],
        });
        const picMap: HashMap<string,string> = new HashMap();
        for (let i = 0; i < list.length; i++) {
            const data = list[i];
            const key = data.totalnum + "," + data.totalsuspectednum;
            if(!picMap.containKey(key)) {
                const options = Utils.getStyle({
                    width: 44,
                    height: 44,
                    offsetX: 22,
                    offsetY: 22,
                    source: this.options.symbolConfig.icons.sickness_0_icon
                }, data.totalnum || 0, data.totalsuspectednum || 0);
                options.source = await Utils.createText(options.scale, options.source,
                    data.totalnum,data.totalsuspectednum);
                options.width = options.width * options.scale;
                options.height = options.height * options.scale;
                options.offsetX = options.offsetX * options.scale;
                options.offsetY = options.offsetY * options.scale;
                options.scale = 1;
                picMap.put(key, options);
            }
        }

        const SymbolBuilder = (G as any).utils.SymbolBuilder.extend({
            build: (data: any) => {
                // options.source = this.options.symbolConfig.icons.sickness_icon;
                //  {
                //     width: 34,
                //     height: 46,
                //     offsetX: 17,
                //     offsetY: 23,
                //     opacity: '1',
                //     rotation: '0',
                //     source: this.options.symbolConfig.icons.demo_icon,
                // };

                // this._addOverlay(data, data.totalnum, data.totalsuspectednum) 暂时屏蔽overlay
                const pos = [data.lng * 1, data.lat * 1];
                this.panLogic.hitTest(pos) && this.panLogic.removePosition();
                return G.utils.RenderUtil.object2Symbol({
                    type: 'PictureMarkerSymbol',
                    options: picMap.getValue(data.totalnum + "," + data.totalsuspectednum)
                })
            },
            buildStyle: function() {
                return {
                    declutter: true,
                }
            }
        });
        opts.symbolBuilder = new SymbolBuilder(),
            opts.listeners = {
                click: (event: any) => {
                    const element: any = event[0].element;
                    console.debug('点击：');
                    console.debug(element);
                    this.closePopup();
                    this._removeHighlight();
                    this._addHighlight(element);
                    this.options.popupManager.addSimple({
                        id: this.options.popupId,
                        anchor: [element.geometry.x, element.geometry.y],
                        className: 'sickness-tooltip',
                    }).then((content: any) => {
                        this.fire(this.options.popupEventName, {
                            data: Utils.attributeSet2Object(element.attributeSet),
                            containerId: content.containerId,
                            type: 'sickness',
                        });
                    });
                },
            };
        this._beforeUpdate()
        this.options.simpleRenderMgr.add(opts);
        // this._fit();
    },
    _beforeUpdate() {
        // 清空overlay
        if (this.overlayWare) {
            this.overlayWare.clear();
        }
        this.closePopup();
        this._removeHighlight();
    },
    /**
     * 根据行政区划等级和中心点改变地图视野
     * @param level 要查询的行政区划等级
     * @param center 选中行政区划的中心点,例：[116,39]
     */
        panTo(level: any, center: any) {
        const zoomLevelMap = this.options.symbolConfig.zoom_level_map;
        const zoom = Object.keys(zoomLevelMap).find((item: any) => zoomLevelMap[item] === level * 1);
        this.map.zoomTo(zoom);

        if (center) {
            if (typeof (center) === 'object') {
                center = [center.lng, center.lat];
            }
            const geo = new g2.sfs.Point({x: center[0], y: center[1]});
            const pos = level === "4" ? center : null
            this.panLogic.setPosition(pos)
            this.map.setCenter(geo);
        }
    },

    // 调整视野
    _fit() {
        const layer: any = this.options.simpleRenderMgr.getLayer(this.options.featureType);
        const extent: any = G.utils.LayerUtil.getLayerExtent(layer);
        this.map.pan(extent, new Array(4).fill(100));
    },

    // 添加高亮
    _addHighlight(element: any) {
        const coordinate: any = [element.geometry.x, element.geometry.y];
        const attr = Utils.attributeSet2Object(element.attributeSet);

        const suspect = attr.totalsuspectednum ? attr.totalsuspectednum : 0;
        const diagnosis = attr.totalnum ? attr.totalnum : 0;
        const opts = Utils.getStyle({
            width: 44,
            height: 44,
            offsetX: 22,
            offsetY: 22,
            source: this.options.symbolConfig.icons.sickness_1_icon
        }, suspect, diagnosis);

        const symbolObj: any = {
            type: 'PictureMarkerSymbol',
            options: opts,
        };
        const options = {
            data: {
                type: 'wkt',
                geom: 'POINT(' + coordinate[0] + ' ' + coordinate[1] + ')',
            },
            style: symbolObj,
            // 不闪烁
            blink: {
                enable: false,
            },
        };
        this.options.featureHighlight.addHighlight(this.options.highLightId, options);
    },

    // 移除高亮
    _removeHighlight() {
        this.options.featureHighlight.removeHighlight(this.options.highLightId);
    },
});

export default component;

































